{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## association_rules: Association rules generation from frequent itemsets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Function to generate association rules from frequent itemsets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> from mlxtend.frequent_patterns import association_rules"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Overview"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Rule generation is a common task in the mining of frequent patterns. _An association rule is an implication expression of the form $X \\rightarrow Y$, where $X$ and $Y$ are disjoint itemsets_ [1]. A more concrete example based on consumer behaviour would be  $\\{Diapers\\} \\rightarrow \\{Beer\\}$ suggesting that people who buy diapers are also likely to buy beer. To evaluate the \"interest\" of such an association rule, different metrics have been developed. The current implementation make use of the `confidence` and `lift` metrics. \n",
    "\n",
    "\n",
    "### Metrics\n",
    "\n",
    "The currently supported metrics for evaluating association rules and setting selection thresholds are listed below. Given a rule \"A -> C\", *A* stands for antecedent and *C* stands for consequent.\n",
    "\n",
    "\n",
    "#### 'support':\n",
    "\n",
    "$$\\text{support}(A\\rightarrow C) = \\text{support}(A \\cup C), \\;\\;\\; \\text{range: } [0, 1]$$\n",
    "\n",
    "- introduced in [3]\n",
    "\n",
    "The support metric is defined for itemsets, not assocication rules. The table produced by the association rule mining algorithm contains three different support metrics: 'antecedent support', 'consequent support', and 'support'. Here, 'antecedent support' computes the proportion of transactions that contain the antecedent A, and 'consequent support' computes the support for the itemset of the consequent C. The 'support' metric then computes the support of the combined itemset A $\\cup$ C.\n",
    "\n",
    "\n",
    "Typically, support is used to measure the abundance or frequency (often interpreted as significance or importance) of an itemset in a database. We refer to an itemset as a \"frequent itemset\" if you support is larger than a specified minimum-support threshold. Note that in general, due to the *downward closure* property, all subsets of a frequent itemset are also frequent.\n",
    "\n",
    "\n",
    "#### 'confidence':  \n",
    "\n",
    "$$\\text{confidence}(A\\rightarrow C) = \\frac{\\text{support}(A\\rightarrow C)}{\\text{support}(A)}, \\;\\;\\; \\text{range: } [0, 1]$$\n",
    "\n",
    "- introduced in [3]\n",
    "\n",
    "The confidence of a rule A->C is the probability of seeing the consequent in a transaction given that it also contains the antecedent. Note that the metric is not symmetric or directed; for instance, the confidence for A->C is different than the confidence for C->A. The confidence is 1 (maximal) for a rule A->C if the consequent and antecedent always occur together. \n",
    "\n",
    "\n",
    "#### 'lift':\n",
    "\n",
    "$$\\text{lift}(A\\rightarrow C) = \\frac{\\text{confidence}(A\\rightarrow C)}{\\text{support}(C)}, \\;\\;\\; \\text{range: } [0, \\infty]$$\n",
    "\n",
    "\n",
    "- introduced in [4]\n",
    "\n",
    "\n",
    "The lift metric is commonly used to measure how much more often the antecedent and consequent of a rule A->C occur together than we would expect if they were statistically independent. If A and C are independent, the Lift score will be exactly 1.\n",
    "\n",
    "\n",
    "#### 'leverage':\n",
    "\n",
    "$$\\text{levarage}(A\\rightarrow C) = \\text{support}(A\\rightarrow C) - \\text{support}(A) \\times \\text{support}(C), \\;\\;\\; \\text{range: } [-1, 1]$$\n",
    "\n",
    "\n",
    "- introduced in [5]\n",
    "\n",
    "Leverage computes the difference between the observed frequency of A and C appearing together and the frequency that would be expected if A and C were independent. A leverage value of 0 indicates independence.\n",
    "\n",
    "#### 'conviction':\n",
    "\n",
    "$$\\text{conviction}(A\\rightarrow C) = \\frac{1 - \\text{support}(C)}{1 - \\text{confidence}(A\\rightarrow C)}, \\;\\;\\; \\text{range: } [0, \\infty]$$\n",
    "\n",
    "- introduced in [6]\n",
    "\n",
    "A high conviction value means that the consequent is highly depending on the antecedent. For instance, in the case of a perfect confidence score, the denominator becomes 0 (due to 1 - 1) for which the conviction score is defined as 'inf'. Similar to lift, if items are independent, the conviction is 1.\n",
    "\n",
    "#### 'zhangs_metric':\n",
    "\n",
    "$$\\text{zhangs metric}(A\\rightarrow C) = \\frac{\\text{confidence}(A\\rightarrow C) - \\text{confidence}(A'\\rightarrow C)}{Max[ \\text{confidence}(A\\rightarrow C) , \\text{confidence}(A'\\rightarrow C)]}, \\;\\;\\; \\text{range: } [-1, 1]$$\n",
    "\n",
    "- introduced in [7]\n",
    "\n",
    "Measures both association and dissociation. Value ranges between -1 and 1. A positive value (>0) indicates Association and negative value indicated dissociation.\n",
    "\n",
    "#### 'jaccard':\n",
    "\n",
    "$$\\text{jaccard}(A\\rightarrow C) = \\frac{\\text{support}(A\\rightarrow C)}{\\text{support}(A) + \\text{support}(C) - \\text{support}(A\\rightarrow C)}, \\;\\;\\; \\text{range: } [0, 1]$$\n",
    "\n",
    "- introduced in [8]\n",
    "\n",
    "Measures similarity between A and C. Value ranges between 0 and 1. A value of 0 indicates complete dissimilarity, and a value of 1 indicates complete similarity.\n",
    " \n",
    "#### 'certainty':\n",
    " $$\\text{certainty}(A\\rightarrow C) = \\frac{\\text{confidence}(A\\rightarrow C) - \\text{support}(C)}{1 - \\text{support}(C)}, \\;\\;\\; \\text{range: } [-1, 1]$$ \n",
    "\n",
    " - introduced in [9]\n",
    " \n",
    " Measures\n",
    "the certainty between A and C. Value ranges from -1 and 1, where 0 indicates independence. \n",
    "\n",
    "#### 'kulczynski':\n",
    " $$\\text{Kulczynski}(A\\rightarrow C) = \\frac{1}{2}\\left(\\frac{\\text{support}(A\\rightarrow C)}{\\text{support}(A)} + \\frac{\\text{support}(A\\rightarrow C)}{\\text{support}(C)}\\right), \\;\\;\\; \\text{range: } [0, 1]$$\n",
    "\n",
    " - introduced in [10]\n",
    "\n",
    " Measures the association between A and C. Value ranges from 0 to 1. Rules near 0 or 1 are considered negatively or positively associated, respectively. Rules near 0.5 are considered to be unintresting.\n",
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Generating association rules with th existence of missing values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As it is already implemented in the FP-Growth/FP-Max algorithms, now the corresponding association rules are generated while addressing the issue of missing information in the input. As before, the supports are used from the algorithm and using these the rest of the metrics are re-formulated in a different way. We still use the so called \"disabled\" array from the original dataframe, where it swaps the null values with ones and the rest with NaNs. For these association rules to make sense, a count corresponding to each sub-case is kept. The cases are when a null value is present in the antecedent, consequent and the combination of both respectively and when there's a NaN in the consequent and all the rest are present in the antecedent and vice versa. According to [11], the metrics are re-defined below:\n",
    "\n",
    "#### 'support':\n",
    " $$\\text{Support}(A\\rightarrow C) = \\frac{|B_{AC}|}{|B| - |\\text{Dis}(AC)|}, \\;\\;\\; \\text{range: } [0, 1]$$\n",
    "\n",
    "where $|B_{AC}|$ is the count of both A and C occuring/existing, $|B|$ is the number of transactions and $|\\text{Dis}(AC)|$ is the count kept if there is a NaN either in A or C, since \n",
    "\n",
    " $$\\text{Dis}(AC) = \\text{Dis}(A)\\cup\\text{Dis}(C)$$\n",
    "\n",
    "#### 'confidence':\n",
    " $$\\text{Confidence}(A\\rightarrow C) = \\frac{|B_{AC}|}{|B_{A}| - |\\text{Dis}(C)\\cap B_{A}|}, \\;\\;\\; \\text{range: } [0, 1]$$\n",
    "\n",
    "where $|\\text{Dis}(C)\\cap B_{A}|$ is the count kept if there is a NaN in C AND an occurence of existence in A. In the code, this formula has been re-arranged using the supports obtained from the algorithm and is formulated as \n",
    " `sAC*(num_itemsets - disAC) / (sA*(num_itemsets - disA) - dis_int)`\n",
    "where `sAC*(num_itemsets - disAC)` is the count kept both in A and C, `sA*(num_itemsets - disA)` is the count kept in A and `dis_int` is the term mentioned above.\n",
    "\n",
    "#### 'representativity':\n",
    " $$\\text{Representativity}(A) = \\frac{|B| - |\\text{Dis}(A)|}{|B|}, \\;\\;\\; \\text{range: } [0, 1]$$\n",
    "\n",
    "- introduced in [11]\n",
    "\n",
    "A new metric induced according to [11], that essentially represents how much information is present in itemset A across all the transactions in the database.\n",
    "\n",
    "The rest of the metrics are derived according to re-formulated support and confidence metrics, while their formulas are kept identical as before but given the \"new\" support and confidence."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## References\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[1] Tan, Steinbach, Kumar. Introduction to Data Mining. Pearson New International Edition. Harlow: Pearson Education Ltd., 2014. (pp. 327-414).\n",
    "\n",
    "[2] Michael Hahsler, https://michael.hahsler.net/research/association_rules/measures.html\n",
    "\n",
    "[3] R. Agrawal, T. Imielinski, and A. Swami. Mining associations between sets of items in large databases. In Proc. of the ACM SIGMOD Int'l Conference on Management of Data, pages 207-216, Washington D.C., May 1993\n",
    "\n",
    "[4] S. Brin, R. Motwani, J. D. Ullman, and S. Tsur. Dynamic itemset counting and implication rules for market basket data\n",
    "\n",
    "[5]  Piatetsky-Shapiro, G., Discovery, analysis, and presentation of strong rules. Knowledge Discovery in Databases, 1991: p. 229-248.\n",
    "\n",
    "[6] Sergey Brin, Rajeev Motwani, Jeffrey D. Ullman, and Shalom Turk. Dynamic itemset counting and implication rules for market basket data. In SIGMOD 1997, Proceedings ACM SIGMOD International Conference on Management of Data, pages 255-264, Tucson, Arizona, USA, May 1997\n",
    "\n",
    "[7]  Xiaowei Yan , Chengqi Zhang & Shichao Zhang (2009) CONFIDENCE METRICS FOR ASSOCIATION RULE MINING, Applied Artificial Intelligence, 23:8, 713-737 https://www.tandfonline.com/doi/pdf/10.1080/08839510903208062.\n",
    "\n",
    "[8] Pang-Ning Tan, Vipin Kumar, Jaideep Srivastava. Selecting the right objective measure for association analysis. Information Systems, Volume 29, Issue 4, 2004, Pages 293-313.\n",
    "\n",
    "[9] Berzal Fernando, Blanco Ignacio, Sánchez Daniel, Vila, María-Amparo. Measuring the accuracy and interest of association rules: A new framework. Intelligent Data Analysis, Volume 6, no. 3, 2002, Pages 221-235.\n",
    "\n",
    "[10] Wu, T., Chen, Y., Han, J. Re-examination of interestingness measures in pattern mining: a unified framework. Data Min Knowl Disc 21, 371–397 (2010). https://doi.org/10.1007/s10618-009-0161-2.\n",
    "\n",
    "[11] Ragel, A. and Crémilleux, B., 1998. \"[Treatment of missing values for association rules](https://link.springer.com/chapter/10.1007/3-540-64383-4_22)\". In Research and Development in Knowledge Discovery and Data Mining: Second Pacific-Asia Conference, PAKDD-98 Melbourne, Australia, April 15–17, 1998 Proceedings 2 (pp. 258-270). Springer Berlin Heidelberg."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 1 -- Generating Association Rules from Frequent Itemsets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `generate_rules` takes dataframes of frequent itemsets as produced by the `apriori`, `fpgrowth`, or `fpmax` functions in *mlxtend.association*. To demonstrate the usage of the `generate_rules` method, we first create a pandas `DataFrame` of frequent itemsets as generated by the [`fpgrowth`](./fpgrowth.md) function:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>support</th>\n",
       "      <th>itemsets</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.0</td>\n",
       "      <td>(Kidney Beans)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.8</td>\n",
       "      <td>(Eggs)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.6</td>\n",
       "      <td>(Yogurt)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.6</td>\n",
       "      <td>(Milk)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.6</td>\n",
       "      <td>(Onion)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0.8</td>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>0.6</td>\n",
       "      <td>(Kidney Beans, Yogurt)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>0.6</td>\n",
       "      <td>(Kidney Beans, Milk)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>0.6</td>\n",
       "      <td>(Onion, Eggs)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>0.6</td>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>0.6</td>\n",
       "      <td>(Kidney Beans, Onion, Eggs)</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    support                     itemsets\n",
       "0       1.0               (Kidney Beans)\n",
       "1       0.8                       (Eggs)\n",
       "2       0.6                     (Yogurt)\n",
       "3       0.6                       (Milk)\n",
       "4       0.6                      (Onion)\n",
       "5       0.8         (Kidney Beans, Eggs)\n",
       "6       0.6       (Kidney Beans, Yogurt)\n",
       "7       0.6         (Kidney Beans, Milk)\n",
       "8       0.6                (Onion, Eggs)\n",
       "9       0.6        (Kidney Beans, Onion)\n",
       "10      0.6  (Kidney Beans, Onion, Eggs)"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "from mlxtend.preprocessing import TransactionEncoder\n",
    "from mlxtend.frequent_patterns import apriori, fpmax, fpgrowth\n",
    "\n",
    "\n",
    "dataset = [['Milk', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],\n",
    "           ['Dill', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],\n",
    "           ['Milk', 'Apple', 'Kidney Beans', 'Eggs'],\n",
    "           ['Milk', 'Unicorn', 'Corn', 'Kidney Beans', 'Yogurt'],\n",
    "           ['Corn', 'Onion', 'Onion', 'Kidney Beans', 'Ice cream', 'Eggs']]\n",
    "\n",
    "te = TransactionEncoder()\n",
    "te_ary = te.fit(dataset).transform(dataset)\n",
    "df = pd.DataFrame(te_ary, columns=te.columns_)\n",
    "\n",
    "frequent_itemsets = fpgrowth(df, min_support=0.6, use_colnames=True)\n",
    "### alternatively:\n",
    "#frequent_itemsets = apriori(df, min_support=0.6, use_colnames=True)\n",
    "#frequent_itemsets = fpmax(df, min_support=0.6, use_colnames=True)\n",
    "\n",
    "frequent_itemsets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `generate_rules()` function allows you to (1) specify your metric of interest and (2) the according threshold. Currently implemented measures are **confidence** and **lift**. Let's say you are interested in rules derived from the frequent itemsets only if the level of confidence is above the 70 percent threshold (`min_threshold=0.7`):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/marcelo/anaconda3/envs/analysis/lib/python3.10/site-packages/mlxtend/frequent_patterns/association_rules.py:182: RuntimeWarning: invalid value encountered in divide\n",
      "  cert_metric = np.where(certainty_denom == 0, 0, certainty_num / certainty_denom)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>antecedent support</th>\n",
       "      <th>consequent support</th>\n",
       "      <th>support</th>\n",
       "      <th>confidence</th>\n",
       "      <th>lift</th>\n",
       "      <th>representativity</th>\n",
       "      <th>leverage</th>\n",
       "      <th>conviction</th>\n",
       "      <th>zhangs_metric</th>\n",
       "      <th>jaccard</th>\n",
       "      <th>certainty</th>\n",
       "      <th>kulczynski</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>(Kidney Beans)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.80</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.80</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Kidney Beans)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.8</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.80</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>(Yogurt)</td>\n",
       "      <td>(Kidney Beans)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.60</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>(Milk)</td>\n",
       "      <td>(Kidney Beans)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.60</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Kidney Beans)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.60</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>(Onion, Eggs)</td>\n",
       "      <td>(Kidney Beans)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.60</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              antecedents            consequents  antecedent support  \\\n",
       "0          (Kidney Beans)                 (Eggs)                 1.0   \n",
       "1                  (Eggs)         (Kidney Beans)                 0.8   \n",
       "2                (Yogurt)         (Kidney Beans)                 0.6   \n",
       "3                  (Milk)         (Kidney Beans)                 0.6   \n",
       "4                 (Onion)                 (Eggs)                 0.6   \n",
       "5                  (Eggs)                (Onion)                 0.8   \n",
       "6                 (Onion)         (Kidney Beans)                 0.6   \n",
       "7   (Kidney Beans, Onion)                 (Eggs)                 0.6   \n",
       "8    (Kidney Beans, Eggs)                (Onion)                 0.8   \n",
       "9           (Onion, Eggs)         (Kidney Beans)                 0.6   \n",
       "10                (Onion)   (Kidney Beans, Eggs)                 0.6   \n",
       "11                 (Eggs)  (Kidney Beans, Onion)                 0.8   \n",
       "\n",
       "    consequent support  support  confidence  lift  representativity  leverage  \\\n",
       "0                  0.8      0.8        0.80  1.00               1.0      0.00   \n",
       "1                  1.0      0.8        1.00  1.00               1.0      0.00   \n",
       "2                  1.0      0.6        1.00  1.00               1.0      0.00   \n",
       "3                  1.0      0.6        1.00  1.00               1.0      0.00   \n",
       "4                  0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "5                  0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "6                  1.0      0.6        1.00  1.00               1.0      0.00   \n",
       "7                  0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "8                  0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "9                  1.0      0.6        1.00  1.00               1.0      0.00   \n",
       "10                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "11                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "\n",
       "    conviction  zhangs_metric  jaccard  certainty  kulczynski  \n",
       "0          1.0            0.0     0.80      0.000       0.900  \n",
       "1          inf            0.0     0.80      0.000       0.900  \n",
       "2          inf            0.0     0.60      0.000       0.800  \n",
       "3          inf            0.0     0.60      0.000       0.800  \n",
       "4          inf            0.5     0.75      1.000       0.875  \n",
       "5          1.6            1.0     0.75      0.375       0.875  \n",
       "6          inf            0.0     0.60      0.000       0.800  \n",
       "7          inf            0.5     0.75      1.000       0.875  \n",
       "8          1.6            1.0     0.75      0.375       0.875  \n",
       "9          inf            0.0     0.60      0.000       0.800  \n",
       "10         inf            0.5     0.75      1.000       0.875  \n",
       "11         1.6            1.0     0.75      0.375       0.875  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from mlxtend.frequent_patterns import association_rules\n",
    "\n",
    "association_rules(frequent_itemsets, metric=\"confidence\", min_threshold=0.7, num_itemsets=len(df.index))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 2 -- Rule Generation and Selection Criteria"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you are interested in rules according to a different metric of interest, you can simply adjust the `metric` and `min_threshold` arguments . E.g. if you are only interested in rules that have a lift score of >= 1.2, you would do the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>antecedent support</th>\n",
       "      <th>consequent support</th>\n",
       "      <th>support</th>\n",
       "      <th>confidence</th>\n",
       "      <th>lift</th>\n",
       "      <th>representativity</th>\n",
       "      <th>leverage</th>\n",
       "      <th>conviction</th>\n",
       "      <th>zhangs_metric</th>\n",
       "      <th>jaccard</th>\n",
       "      <th>certainty</th>\n",
       "      <th>kulczynski</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             antecedents            consequents  antecedent support  \\\n",
       "0                (Onion)                 (Eggs)                 0.6   \n",
       "1                 (Eggs)                (Onion)                 0.8   \n",
       "2  (Kidney Beans, Onion)                 (Eggs)                 0.6   \n",
       "3   (Kidney Beans, Eggs)                (Onion)                 0.8   \n",
       "4                (Onion)   (Kidney Beans, Eggs)                 0.6   \n",
       "5                 (Eggs)  (Kidney Beans, Onion)                 0.8   \n",
       "\n",
       "   consequent support  support  confidence  lift  representativity  leverage  \\\n",
       "0                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "1                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "2                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "3                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "4                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "5                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "\n",
       "   conviction  zhangs_metric  jaccard  certainty  kulczynski  \n",
       "0         inf            0.5     0.75      1.000       0.875  \n",
       "1         1.6            1.0     0.75      0.375       0.875  \n",
       "2         inf            0.5     0.75      1.000       0.875  \n",
       "3         1.6            1.0     0.75      0.375       0.875  \n",
       "4         inf            0.5     0.75      1.000       0.875  \n",
       "5         1.6            1.0     0.75      0.375       0.875  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rules = association_rules(frequent_itemsets, metric=\"lift\", min_threshold=1.2, num_itemsets=len(df.index))\n",
    "rules"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pandas `DataFrames` make it easy to filter the results further. Let's say we are ony interested in rules that satisfy the following criteria:\n",
    "\n",
    "1. at least 2 antecedents\n",
    "2. a confidence > 0.75\n",
    "3. a lift score > 1.2\n",
    "\n",
    "We could compute the antecedent length as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>antecedent support</th>\n",
       "      <th>consequent support</th>\n",
       "      <th>support</th>\n",
       "      <th>confidence</th>\n",
       "      <th>lift</th>\n",
       "      <th>representativity</th>\n",
       "      <th>leverage</th>\n",
       "      <th>conviction</th>\n",
       "      <th>zhangs_metric</th>\n",
       "      <th>jaccard</th>\n",
       "      <th>certainty</th>\n",
       "      <th>kulczynski</th>\n",
       "      <th>antecedent_len</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             antecedents            consequents  antecedent support  \\\n",
       "0                (Onion)                 (Eggs)                 0.6   \n",
       "1                 (Eggs)                (Onion)                 0.8   \n",
       "2  (Kidney Beans, Onion)                 (Eggs)                 0.6   \n",
       "3   (Kidney Beans, Eggs)                (Onion)                 0.8   \n",
       "4                (Onion)   (Kidney Beans, Eggs)                 0.6   \n",
       "5                 (Eggs)  (Kidney Beans, Onion)                 0.8   \n",
       "\n",
       "   consequent support  support  confidence  lift  representativity  leverage  \\\n",
       "0                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "1                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "2                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "3                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "4                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "5                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "\n",
       "   conviction  zhangs_metric  jaccard  certainty  kulczynski  antecedent_len  \n",
       "0         inf            0.5     0.75      1.000       0.875               1  \n",
       "1         1.6            1.0     0.75      0.375       0.875               1  \n",
       "2         inf            0.5     0.75      1.000       0.875               2  \n",
       "3         1.6            1.0     0.75      0.375       0.875               2  \n",
       "4         inf            0.5     0.75      1.000       0.875               1  \n",
       "5         1.6            1.0     0.75      0.375       0.875               1  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rules[\"antecedent_len\"] = rules[\"antecedents\"].apply(lambda x: len(x))\n",
    "rules"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, we can use pandas' selection syntax as shown below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>antecedent support</th>\n",
       "      <th>consequent support</th>\n",
       "      <th>support</th>\n",
       "      <th>confidence</th>\n",
       "      <th>lift</th>\n",
       "      <th>representativity</th>\n",
       "      <th>leverage</th>\n",
       "      <th>conviction</th>\n",
       "      <th>zhangs_metric</th>\n",
       "      <th>jaccard</th>\n",
       "      <th>certainty</th>\n",
       "      <th>kulczynski</th>\n",
       "      <th>antecedent_len</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.875</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             antecedents consequents  antecedent support  consequent support  \\\n",
       "2  (Kidney Beans, Onion)      (Eggs)                 0.6                 0.8   \n",
       "\n",
       "   support  confidence  lift  representativity  leverage  conviction  \\\n",
       "2      0.6         1.0  1.25               1.0      0.12         inf   \n",
       "\n",
       "   zhangs_metric  jaccard  certainty  kulczynski  antecedent_len  \n",
       "2            0.5     0.75        1.0       0.875               2  "
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rules[ (rules['antecedent_len'] >= 2) &\n",
    "       (rules['confidence'] > 0.75) &\n",
    "       (rules['lift'] > 1.2) ]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similarly, using the Pandas API, we can select entries based on the \"antecedents\" or \"consequents\" columns:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>antecedent support</th>\n",
       "      <th>consequent support</th>\n",
       "      <th>support</th>\n",
       "      <th>confidence</th>\n",
       "      <th>lift</th>\n",
       "      <th>representativity</th>\n",
       "      <th>leverage</th>\n",
       "      <th>conviction</th>\n",
       "      <th>zhangs_metric</th>\n",
       "      <th>jaccard</th>\n",
       "      <th>certainty</th>\n",
       "      <th>kulczynski</th>\n",
       "      <th>antecedent_len</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            antecedents consequents  antecedent support  consequent support  \\\n",
       "3  (Kidney Beans, Eggs)     (Onion)                 0.8                 0.6   \n",
       "\n",
       "   support  confidence  lift  representativity  leverage  conviction  \\\n",
       "3      0.6        0.75  1.25               1.0      0.12         1.6   \n",
       "\n",
       "   zhangs_metric  jaccard  certainty  kulczynski  antecedent_len  \n",
       "3            1.0     0.75      0.375       0.875               2  "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rules[rules['antecedents'] == {'Eggs', 'Kidney Beans'}]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Frozensets**\n",
    "\n",
    "Note that the entries in the \"itemsets\" column are of type `frozenset`, which is built-in Python type that is similar to a Python `set` but immutable, which makes it more efficient for certain query or comparison operations (https://docs.python.org/3.6/library/stdtypes.html#frozenset). Since `frozenset`s are sets, the item order does not matter. I.e., the query\n",
    "\n",
    "`rules[rules['antecedents'] == {'Eggs', 'Kidney Beans'}]`\n",
    "    \n",
    "is equivalent to any of the following three\n",
    "\n",
    "- `rules[rules['antecedents'] == {'Kidney Beans', 'Eggs'}]`\n",
    "- `rules[rules['antecedents'] == frozenset(('Eggs', 'Kidney Beans'))]`\n",
    "- `rules[rules['antecedents'] == frozenset(('Kidney Beans', 'Eggs'))]`\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 3 -- Frequent Itemsets with Incomplete Antecedent and Consequent Information"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Most metrics computed by `association_rules` depends on the consequent and antecedent support score of a given rule provided in the frequent itemset input DataFrame. Consider the following example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>itemsets</th>\n",
       "      <th>support</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>[177, 176]</td>\n",
       "      <td>0.253623</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[177, 179]</td>\n",
       "      <td>0.253623</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[176, 178]</td>\n",
       "      <td>0.217391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[176, 179]</td>\n",
       "      <td>0.217391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>[93, 100]</td>\n",
       "      <td>0.181159</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>[177, 178]</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>[177, 176, 178]</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          itemsets   support\n",
       "0       [177, 176]  0.253623\n",
       "1       [177, 179]  0.253623\n",
       "2       [176, 178]  0.217391\n",
       "3       [176, 179]  0.217391\n",
       "4        [93, 100]  0.181159\n",
       "5       [177, 178]  0.108696\n",
       "6  [177, 176, 178]  0.108696"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "dict = {'itemsets': [['177', '176'], ['177', '179'],\n",
    "                     ['176', '178'], ['176', '179'],\n",
    "                     ['93', '100'], ['177', '178'],\n",
    "                     ['177', '176', '178']],\n",
    "        'support':[0.253623, 0.253623, 0.217391,\n",
    "                   0.217391, 0.181159, 0.108696, 0.108696]}\n",
    "\n",
    "freq_itemsets = pd.DataFrame(dict)\n",
    "freq_itemsets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that this is a \"cropped\" DataFrame that doesn't contain the support values of the item subsets. This can create problems if we want to compute the association rule metrics for, e.g., `176 => 177`.\n",
    "\n",
    "For example, the confidence is computed as\n",
    "\n",
    "$$\\text{confidence}(A\\rightarrow C) = \\frac{\\text{support}(A\\rightarrow C)}{\\text{support}(A)}, \\;\\;\\; \\text{range: } [0, 1]$$\n",
    "\n",
    "But we do not have $\\text{support}(A)$. All we know about \"A\"'s support is that it is at least 0.253623.\n",
    "\n",
    "In these scenarios, where not all metric's can be computed, due to incomplete input DataFrames, you can use the `support_only=True` option, which will only compute the support column of a given rule that does not require as much info:\n",
    "\n",
    "$$\\text{support}(A\\rightarrow C) = \\text{support}(A \\cup C), \\;\\;\\; \\text{range: } [0, 1]$$\n",
    "\n",
    "\n",
    "\"NaN's\" will be assigned to all other metric columns:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>antecedent support</th>\n",
       "      <th>consequent support</th>\n",
       "      <th>support</th>\n",
       "      <th>confidence</th>\n",
       "      <th>lift</th>\n",
       "      <th>representativity</th>\n",
       "      <th>leverage</th>\n",
       "      <th>conviction</th>\n",
       "      <th>zhangs_metric</th>\n",
       "      <th>jaccard</th>\n",
       "      <th>certainty</th>\n",
       "      <th>kulczynski</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>(176)</td>\n",
       "      <td>(177)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.253623</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>(177)</td>\n",
       "      <td>(176)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.253623</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>(179)</td>\n",
       "      <td>(177)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.253623</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>(177)</td>\n",
       "      <td>(179)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.253623</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>(176)</td>\n",
       "      <td>(178)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.217391</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>(178)</td>\n",
       "      <td>(176)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.217391</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>(176)</td>\n",
       "      <td>(179)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.217391</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>(179)</td>\n",
       "      <td>(176)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.217391</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>(100)</td>\n",
       "      <td>(93)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.181159</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>(93)</td>\n",
       "      <td>(100)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.181159</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>(178)</td>\n",
       "      <td>(177)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.108696</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>(177)</td>\n",
       "      <td>(178)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.108696</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>(176, 178)</td>\n",
       "      <td>(177)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.108696</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>(176, 177)</td>\n",
       "      <td>(178)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.108696</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>(178, 177)</td>\n",
       "      <td>(176)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.108696</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>(176)</td>\n",
       "      <td>(178, 177)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.108696</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>(178)</td>\n",
       "      <td>(176, 177)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.108696</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>(177)</td>\n",
       "      <td>(176, 178)</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.108696</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   antecedents consequents  antecedent support  consequent support   support  \\\n",
       "0        (176)       (177)                 NaN                 NaN  0.253623   \n",
       "1        (177)       (176)                 NaN                 NaN  0.253623   \n",
       "2        (179)       (177)                 NaN                 NaN  0.253623   \n",
       "3        (177)       (179)                 NaN                 NaN  0.253623   \n",
       "4        (176)       (178)                 NaN                 NaN  0.217391   \n",
       "5        (178)       (176)                 NaN                 NaN  0.217391   \n",
       "6        (176)       (179)                 NaN                 NaN  0.217391   \n",
       "7        (179)       (176)                 NaN                 NaN  0.217391   \n",
       "8        (100)        (93)                 NaN                 NaN  0.181159   \n",
       "9         (93)       (100)                 NaN                 NaN  0.181159   \n",
       "10       (178)       (177)                 NaN                 NaN  0.108696   \n",
       "11       (177)       (178)                 NaN                 NaN  0.108696   \n",
       "12  (176, 178)       (177)                 NaN                 NaN  0.108696   \n",
       "13  (176, 177)       (178)                 NaN                 NaN  0.108696   \n",
       "14  (178, 177)       (176)                 NaN                 NaN  0.108696   \n",
       "15       (176)  (178, 177)                 NaN                 NaN  0.108696   \n",
       "16       (178)  (176, 177)                 NaN                 NaN  0.108696   \n",
       "17       (177)  (176, 178)                 NaN                 NaN  0.108696   \n",
       "\n",
       "    confidence  lift  representativity  leverage  conviction  zhangs_metric  \\\n",
       "0          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "1          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "2          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "3          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "4          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "5          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "6          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "7          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "8          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "9          NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "10         NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "11         NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "12         NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "13         NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "14         NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "15         NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "16         NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "17         NaN   NaN               NaN       NaN         NaN            NaN   \n",
       "\n",
       "    jaccard  certainty  kulczynski  \n",
       "0       NaN        NaN         NaN  \n",
       "1       NaN        NaN         NaN  \n",
       "2       NaN        NaN         NaN  \n",
       "3       NaN        NaN         NaN  \n",
       "4       NaN        NaN         NaN  \n",
       "5       NaN        NaN         NaN  \n",
       "6       NaN        NaN         NaN  \n",
       "7       NaN        NaN         NaN  \n",
       "8       NaN        NaN         NaN  \n",
       "9       NaN        NaN         NaN  \n",
       "10      NaN        NaN         NaN  \n",
       "11      NaN        NaN         NaN  \n",
       "12      NaN        NaN         NaN  \n",
       "13      NaN        NaN         NaN  \n",
       "14      NaN        NaN         NaN  \n",
       "15      NaN        NaN         NaN  \n",
       "16      NaN        NaN         NaN  \n",
       "17      NaN        NaN         NaN  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from mlxtend.frequent_patterns import association_rules\n",
    "\n",
    "res = association_rules(freq_itemsets, support_only=True, min_threshold=0.1, num_itemsets=0)\n",
    "res"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To clean up the representation, you may want to do the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>support</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>(176)</td>\n",
       "      <td>(177)</td>\n",
       "      <td>0.253623</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>(177)</td>\n",
       "      <td>(176)</td>\n",
       "      <td>0.253623</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>(179)</td>\n",
       "      <td>(177)</td>\n",
       "      <td>0.253623</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>(177)</td>\n",
       "      <td>(179)</td>\n",
       "      <td>0.253623</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>(176)</td>\n",
       "      <td>(178)</td>\n",
       "      <td>0.217391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>(178)</td>\n",
       "      <td>(176)</td>\n",
       "      <td>0.217391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>(176)</td>\n",
       "      <td>(179)</td>\n",
       "      <td>0.217391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>(179)</td>\n",
       "      <td>(176)</td>\n",
       "      <td>0.217391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>(100)</td>\n",
       "      <td>(93)</td>\n",
       "      <td>0.181159</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>(93)</td>\n",
       "      <td>(100)</td>\n",
       "      <td>0.181159</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>(178)</td>\n",
       "      <td>(177)</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>(177)</td>\n",
       "      <td>(178)</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>(176, 178)</td>\n",
       "      <td>(177)</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>(176, 177)</td>\n",
       "      <td>(178)</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>(178, 177)</td>\n",
       "      <td>(176)</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>(176)</td>\n",
       "      <td>(178, 177)</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>(178)</td>\n",
       "      <td>(176, 177)</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>(177)</td>\n",
       "      <td>(176, 178)</td>\n",
       "      <td>0.108696</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   antecedents consequents   support\n",
       "0        (176)       (177)  0.253623\n",
       "1        (177)       (176)  0.253623\n",
       "2        (179)       (177)  0.253623\n",
       "3        (177)       (179)  0.253623\n",
       "4        (176)       (178)  0.217391\n",
       "5        (178)       (176)  0.217391\n",
       "6        (176)       (179)  0.217391\n",
       "7        (179)       (176)  0.217391\n",
       "8        (100)        (93)  0.181159\n",
       "9         (93)       (100)  0.181159\n",
       "10       (178)       (177)  0.108696\n",
       "11       (177)       (178)  0.108696\n",
       "12  (176, 178)       (177)  0.108696\n",
       "13  (176, 177)       (178)  0.108696\n",
       "14  (178, 177)       (176)  0.108696\n",
       "15       (176)  (178, 177)  0.108696\n",
       "16       (178)  (176, 177)  0.108696\n",
       "17       (177)  (176, 178)  0.108696"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res = res[['antecedents', 'consequents', 'support']]\n",
    "res"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 4 -- Pruning Association Rules"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There is no specific API for pruning. Instead, the pandas API can be used on the resulting data frame to remove individual rows. E.g., suppose we have the following rules:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>antecedent support</th>\n",
       "      <th>consequent support</th>\n",
       "      <th>support</th>\n",
       "      <th>confidence</th>\n",
       "      <th>lift</th>\n",
       "      <th>representativity</th>\n",
       "      <th>leverage</th>\n",
       "      <th>conviction</th>\n",
       "      <th>zhangs_metric</th>\n",
       "      <th>jaccard</th>\n",
       "      <th>certainty</th>\n",
       "      <th>kulczynski</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             antecedents            consequents  antecedent support  \\\n",
       "0                (Onion)                 (Eggs)                 0.6   \n",
       "1                 (Eggs)                (Onion)                 0.8   \n",
       "2  (Kidney Beans, Onion)                 (Eggs)                 0.6   \n",
       "3   (Kidney Beans, Eggs)                (Onion)                 0.8   \n",
       "4                (Onion)   (Kidney Beans, Eggs)                 0.6   \n",
       "5                 (Eggs)  (Kidney Beans, Onion)                 0.8   \n",
       "\n",
       "   consequent support  support  confidence  lift  representativity  leverage  \\\n",
       "0                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "1                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "2                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "3                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "4                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "5                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "\n",
       "   conviction  zhangs_metric  jaccard  certainty  kulczynski  \n",
       "0         inf            0.5     0.75      1.000       0.875  \n",
       "1         1.6            1.0     0.75      0.375       0.875  \n",
       "2         inf            0.5     0.75      1.000       0.875  \n",
       "3         1.6            1.0     0.75      0.375       0.875  \n",
       "4         inf            0.5     0.75      1.000       0.875  \n",
       "5         1.6            1.0     0.75      0.375       0.875  "
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "from mlxtend.preprocessing import TransactionEncoder\n",
    "from mlxtend.frequent_patterns import apriori, fpmax, fpgrowth\n",
    "from mlxtend.frequent_patterns import association_rules\n",
    "\n",
    "\n",
    "dataset = [['Milk', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],\n",
    "           ['Dill', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],\n",
    "           ['Milk', 'Apple', 'Kidney Beans', 'Eggs'],\n",
    "           ['Milk', 'Unicorn', 'Corn', 'Kidney Beans', 'Yogurt'],\n",
    "           ['Corn', 'Onion', 'Onion', 'Kidney Beans', 'Ice cream', 'Eggs']]\n",
    "\n",
    "te = TransactionEncoder()\n",
    "te_ary = te.fit(dataset).transform(dataset)\n",
    "df = pd.DataFrame(te_ary, columns=te.columns_)\n",
    "\n",
    "frequent_itemsets = fpgrowth(df, min_support=0.6, use_colnames=True)\n",
    "rules = association_rules(frequent_itemsets, metric=\"lift\", min_threshold=1.2, num_itemsets=len(df.index))\n",
    "rules"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "and we want to remove the rule \"(Onion, Kidney Beans) -> (Eggs)\". In order to to this, we can define selection masks and remove this row as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>antecedent support</th>\n",
       "      <th>consequent support</th>\n",
       "      <th>support</th>\n",
       "      <th>confidence</th>\n",
       "      <th>lift</th>\n",
       "      <th>representativity</th>\n",
       "      <th>leverage</th>\n",
       "      <th>conviction</th>\n",
       "      <th>zhangs_metric</th>\n",
       "      <th>jaccard</th>\n",
       "      <th>certainty</th>\n",
       "      <th>kulczynski</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>(Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>(Onion)</td>\n",
       "      <td>(Kidney Beans, Eggs)</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Kidney Beans, Onion)</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.25</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.12</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>0.375</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            antecedents            consequents  antecedent support  \\\n",
       "0               (Onion)                 (Eggs)                 0.6   \n",
       "1                (Eggs)                (Onion)                 0.8   \n",
       "3  (Kidney Beans, Eggs)                (Onion)                 0.8   \n",
       "4               (Onion)   (Kidney Beans, Eggs)                 0.6   \n",
       "5                (Eggs)  (Kidney Beans, Onion)                 0.8   \n",
       "\n",
       "   consequent support  support  confidence  lift  representativity  leverage  \\\n",
       "0                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "1                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "3                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "4                 0.8      0.6        1.00  1.25               1.0      0.12   \n",
       "5                 0.6      0.6        0.75  1.25               1.0      0.12   \n",
       "\n",
       "   conviction  zhangs_metric  jaccard  certainty  kulczynski  \n",
       "0         inf            0.5     0.75      1.000       0.875  \n",
       "1         1.6            1.0     0.75      0.375       0.875  \n",
       "3         1.6            1.0     0.75      0.375       0.875  \n",
       "4         inf            0.5     0.75      1.000       0.875  \n",
       "5         1.6            1.0     0.75      0.375       0.875  "
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "antecedent_sele = rules['antecedents'] == frozenset({'Onion', 'Kidney Beans'}) # or  frozenset({'Kidney Beans', 'Onion'})\n",
    "consequent_sele = rules['consequents'] == frozenset({'Eggs'})\n",
    "final_sele = (antecedent_sele & consequent_sele)\n",
    "\n",
    "rules.loc[ ~final_sele ]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 5 -- Generating Association Rules from data with missing information"
   ]
  },
  {
   "cell_type": "code",

   "execution_count": 20,

   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [

      "/tmp/ipykernel_34953/2823279667.py:23: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value 'nan' has dtype incompatible with bool, please explicitly cast to a compatible dtype first.\n",
      "  df.iloc[idx[i], col[i]] = np.nan\n",
      "/tmp/ipykernel_34953/2823279667.py:23: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value 'nan' has dtype incompatible with bool, please explicitly cast to a compatible dtype first.\n",
      "  df.iloc[idx[i], col[i]] = np.nan\n",
      "/tmp/ipykernel_34953/2823279667.py:23: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value 'nan' has dtype incompatible with bool, please explicitly cast to a compatible dtype first.\n",
      "  df.iloc[idx[i], col[i]] = np.nan\n",
      "/tmp/ipykernel_34953/2823279667.py:23: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value 'nan' has dtype incompatible with bool, please explicitly cast to a compatible dtype first.\n",
      "  df.iloc[idx[i], col[i]] = np.nan\n",
      "/tmp/ipykernel_34953/2823279667.py:23: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value 'nan' has dtype incompatible with bool, please explicitly cast to a compatible dtype first.\n",
      "  df.iloc[idx[i], col[i]] = np.nan\n",
      "/tmp/ipykernel_34953/2823279667.py:23: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value 'nan' has dtype incompatible with bool, please explicitly cast to a compatible dtype first.\n",
      "  df.iloc[idx[i], col[i]] = np.nan\n",
      "/tmp/ipykernel_34953/2823279667.py:23: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value 'nan' has dtype incompatible with bool, please explicitly cast to a compatible dtype first.\n",

      "  df.iloc[idx[i], col[i]] = np.nan\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Apple</th>\n",
       "      <th>Corn</th>\n",
       "      <th>Dill</th>\n",
       "      <th>Eggs</th>\n",
       "      <th>Ice cream</th>\n",
       "      <th>Kidney Beans</th>\n",
       "      <th>Milk</th>\n",
       "      <th>Nutmeg</th>\n",
       "      <th>Onion</th>\n",
       "      <th>Unicorn</th>\n",
       "      <th>Yogurt</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>NaN</td>\n",

       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>False</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>False</td>\n",
       "      <td>NaN</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Apple   Corn   Dill   Eggs Ice cream Kidney Beans   Milk  Nutmeg  Onion  \\\n",
       "0  False  False  False   True     False         True   True    True   True   \n",
       "1  False  False   True   True     False          NaN    NaN    True    NaN   \n",
       "2   True  False  False   True     False         True   True   False  False   \n",
       "3  False   True  False  False     False         True   True   False  False   \n",
       "4  False    NaN  False   True       NaN         True  False   False    NaN   \n",
       "\n",
       "  Unicorn Yogurt  \n",
       "0   False    NaN  \n",
       "1   False    NaN  \n",
       "2   False  False  \n",
       "3    True   True  \n",
       "4     NaN  False  "
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from mlxtend.preprocessing import TransactionEncoder\n",
    "from mlxtend.frequent_patterns import apriori, fpmax, fpgrowth\n",
    "from mlxtend.frequent_patterns import association_rules\n",
    "\n",
    "\n",
    "dataset = [['Milk', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],\n",
    "           ['Dill', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],\n",
    "           ['Milk', 'Apple', 'Kidney Beans', 'Eggs'],\n",
    "           ['Milk', 'Unicorn', 'Corn', 'Kidney Beans', 'Yogurt'],\n",
    "           ['Corn', 'Onion', 'Onion', 'Kidney Beans', 'Ice cream', 'Eggs']]\n",
    "\n",
    "te = TransactionEncoder()\n",
    "te_ary = te.fit(dataset).transform(dataset)\n",
    "df = pd.DataFrame(te_ary, columns=te.columns_)\n",
    "\n",
    "rows, columns = df.shape\n",
    "idx = np.random.randint(0, rows, 10)\n",
    "col = np.random.randint(0, columns, 10)\n",
    "\n",
    "for i in range(10):\n",
    "    df.iloc[idx[i], col[i]] = np.nan\n",
    "\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The example below, shows the same implementations as above but with the case when a dataset has missing values. The function still allows you to (1) specify your metric of interest and (2) the according threshold. Now we have to set `null_values=True` to both `fpgrowth`/`fpmax` and also include the original `df` and its size as parameters to the function. We try the example below using `metric=\"confidence\"` and `min_threshold=0.8`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/marcelo/anaconda3/envs/analysis/lib/python3.10/site-packages/mlxtend/frequent_patterns/association_rules.py:182: RuntimeWarning: invalid value encountered in divide\n",
      "  cert_metric = np.where(certainty_denom == 0, 0, certainty_num / certainty_denom)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>antecedents</th>\n",
       "      <th>consequents</th>\n",
       "      <th>antecedent support</th>\n",
       "      <th>consequent support</th>\n",
       "      <th>support</th>\n",
       "      <th>confidence</th>\n",
       "      <th>lift</th>\n",
       "      <th>representativity</th>\n",
       "      <th>leverage</th>\n",
       "      <th>conviction</th>\n",
       "      <th>zhangs_metric</th>\n",
       "      <th>jaccard</th>\n",
       "      <th>certainty</th>\n",
       "      <th>kulczynski</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>(Eggs)</td>\n",
       "      <td>(Kidney Beans)</td>\n",
       "      <td>0.80</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.8</td>\n",
       "      <td>-0.05</td>\n",
       "      <td>inf</td>\n",
       "      <td>-0.25</td>\n",
       "      <td>0.714286</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>(Milk)</td>\n",
       "      <td>(Kidney Beans)</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.00</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.750000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.875</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  antecedents     consequents  antecedent support  consequent support  \\\n",
       "0      (Eggs)  (Kidney Beans)                0.80                 1.0   \n",
       "1      (Milk)  (Kidney Beans)                0.75                 1.0   \n",
       "\n",
       "   support  confidence  lift  representativity  leverage  conviction  \\\n",
       "0     0.75         1.0   1.0               0.8     -0.05         inf   \n",
       "1     0.75         1.0   1.0               0.8      0.00         inf   \n",
       "\n",
       "   zhangs_metric   jaccard  certainty  kulczynski  \n",
       "0          -0.25  0.714286        0.0       0.875  \n",
       "1           0.00  0.750000        0.0       0.875  "
      ]
     },
     "execution_count": 21,

     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frequent_itemsets = fpgrowth(df, min_support=0.6, null_values = True, use_colnames=True)\n",
    "# frequent_itemsets = fpmax(df, min_support=0.6, null_values = True, use_colnames=True)\n",
    "rules = association_rules(frequent_itemsets, len(df), df, null_values = True, metric=\"confidence\", min_threshold=0.8)\n",

    "rules"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('../../api_modules/mlxtend.frequent_patterns/association_rules.md', 'r') as f:\n",
    "    print(f.read())"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
